home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
comm
/
msged400.zip
/
src
/
fido.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-24
|
19KB
|
694 lines
/*
* FIDO.C
*
* Written on 30-Jul-90 by jim nutt. Changes on 10-Jul-94 by John Dennis.
* Released to the public domain.
*
* Fido/Opus style message base support functions for Msged.
*
* NOTE: These routines are slated for extinction in the near future.
* They're to be replaced by the Squish msgAPI. Possibly.
*
* 17-Dec-91 Added share support to all file routines and converted ANSI
* file access code to low level read()/write().
* 26-Jan-92 Fixed bug in msg routines that seemed to cause a crash on
* zero length msgs (zero, as in no ctrl info and text).
* 23-Feb-92 Removed locking routines.
* 01-Apr-92 Made New msgs remain open until writing the text, also added
* some kludge code to handle the reading of Opus msgs.
* 12-Jul-92 Added some more functions to make the interface solid.
* 03-Dec-92 Fix to WriteHeader.
*/
#define CHUNKSZ 256
#define TEXTLEN 96
#define NO_STDLIB /* causes conflicts with errno.h with MSC */
#include <errno.h>
#include "msged.h"
#include "date.h"
#include "memextra.h"
#ifdef __MSC__
#include <sys\locking.h>
#endif
#if defined(PACIFIC)
#include <unixio.h>
#define O_WRONLY 0x0001
#define O_BINARY 0x0000
#define O_CREAT 0x0000
#define O_RDWR 0x0002
#define O_RDONLY 0x0000
#define S_IREAD 0x0100
#define S_IWRITE 0x0080
#define EACCES 0x18
#define EMFILE 0x19
#define SH_DENYNO 0x40
int sopen(char *filename, unsigned int access, int flags,...);
#elif defined(SASC)
#define SH_DENYNO 0x40
#define sopen(a,b,c,d) open(a,b)
#include <fcntl.h>
#elif defined(UNIX)
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define sopen(a,b,c,d) open(a,b)
#define O_BINARY 0x0000
#else
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <share.h>
#include <fcntl.h>
#endif
/* file access shortcuts */
#define OPENR O_RDONLY|O_BINARY /* open read-only */
#define OPENC O_WRONLY|O_BINARY|O_CREAT /* open/create */
#define OPENRW O_RDWR|O_BINARY /* open read/write */
#define S_IMODE S_IREAD|S_IWRITE /* open mode */
/* prototypes */
#include "normal.h"
static int compare(const void *i, const void *j);
/* structures used in this module */
typedef struct _dosdate
{
unsigned int day:5;
unsigned int mon:4;
unsigned int year:7;
unsigned int sec:5;
unsigned int min:6;
unsigned int hour:5;
}
DOSDATE;
static time_t dosdateToTimeT(DOSDATE * st);
typedef struct _fidoheader
{
char from[36]; /* who from, */
char to[36]; /* who to, */
char subj[72]; /* message subject, */
char date[20]; /* creation date, */
unsigned char times[2]; /* number of times read, */
unsigned char dest[2]; /* destination node, */
unsigned char orig[2]; /* originating node */
unsigned char cost[2]; /* actual cost this msg */
unsigned char orig_net[2]; /* originating net */
unsigned char dest_net[2]; /* destination net */
unsigned char written[4]; /* when it was written */
unsigned char arrived[4]; /* when it arrived */
unsigned char reply[2]; /* thread to previous msg */
unsigned char attrib[2]; /* message attributes */
unsigned char up[2]; /* thread to next msg */
}
MFIDO;
/* local vars */
static int fp = -1; /* current file handle */
static unsigned long *msgarr = NULL; /* array of *.msg numbers */
static unsigned long msgarrsz = 0; /* # of numbers in the array */
static unsigned long oldsz = 0; /* total size of the array */
static void timet_to_char(time_t now, unsigned char arr[])
{
struct tm *ts;
unsigned long x;
ts = localtime(&now);
x = ts->tm_year - 80;
x = (x << 4) | (ts->tm_mon + 1);
x = (x << 5) | ts->tm_mday;
x = (x << 5) | ts->tm_hour;
x = (x << 6) | ts->tm_min;
x = (x << 5) | (ts->tm_sec / 2);
arr[0] = (unsigned char)((x >> 16) & 0xff);
arr[1] = (unsigned char)((x >> 24) & 0xff);
arr[2] = (unsigned char)(x & 0xff);
arr[3] = (unsigned char)((x >> 8) & 0xff);
}
unsigned long FidoMsgnToUid(unsigned long n)
{
if (n > msgarrsz || n == 0)
return 0;
return msgarr[(size_t) (n - 1)];
}
unsigned long FidoUidToMsgn(unsigned long n)
{
unsigned long i;
for (i = 0; i < msgarrsz; i++)
if (msgarr[(size_t) i] == n)
break;
return (i == msgarrsz) ? 0 : i + 1;
}
int FidoMsgWriteText(char *text, unsigned long n, unsigned long mlen)
{
char i = 0;
unused(n);
unused(mlen);
if (text == NULL)
{
write(fp, &i, sizeof(char));
return (TRUE);
}
write(fp, text, strlen(text));
return TRUE;
}
int FidoMsgWriteHeader(msg * m, int type)
{
MFIDO msghead;
static char path[PATHLEN];
time_t now = time(NULL);
unsigned long n = m->msgnum;
int done = 0;
unsigned long x;
if (fp != -1)
{
close(fp);
fp = -1;
}
sprintf(path, "%s/%lu.msg", CurArea.path, n);
if (m->new)
{
while (!done)
{
if ((fp = sopen(path, OPENR, SH_DENYNO, S_IMODE)) != -1)
{
close(fp);
fp = -1;
n++;
}
else
{
if ((fp = sopen(path, OPENC, SH_DENYNO, S_IMODE)) == -1)
return (ERR_OPEN_MSG);
done = 1;
}
sprintf(path, "%s/%lu.msg", CurArea.path, n);
}
}
else
{
if ((fp = sopen(path, OPENRW, SH_DENYNO, S_IMODE)) == -1)
return (ERR_OPEN_MSG);
}
if (m->new)
{
if ((++msgarrsz) > oldsz)
{
unsigned long *t;
t = xcalloc(1, (size_t) ((oldsz += CHUNKSZ) * sizeof *t));
memcpy(t, msgarr, (size_t) (sizeof(unsigned long) * msgarrsz));
release(msgarr);
msgarr = t;
}
msgarr[(size_t) (msgarrsz - 1)] = n;
}
memset(&msghead, 0, sizeof msghead);
m->msgnum = n;
msghead.attrib[0] = (unsigned char)
((m->attrib.killsent << 7)
| (m->attrib.orphan << 6)
| (m->attrib.forward << 5)
| (m->attrib.attach << 4)
| (m->attrib.sent << 3)
| (m->attrib.rcvd << 2)
| (m->attrib.crash << 1)
| (m->attrib.priv));
msghead.attrib[1] = (unsigned char)
((m->attrib.ureq << 7)
| (m->attrib.areq << 6)
| (m->attrib.rcpt << 5)
| (m->attrib.rreq << 4)
| (m->attrib.freq << 3)
| (m->attrib.direct << 2)
| (m->attrib.hold << 1)
| (m->attrib.local));
x = FidoMsgnToUid((unsigned long)m->replyto);
msghead.reply[0] = (unsigned char)(x & 0xff);
msghead.reply[1] = (unsigned char)((x >> 8) & 0xff);
x = FidoMsgnToUid((unsigned long)m->replies[0]);
msghead.up[0] = (unsigned char)(x & 0xff);
msghead.up[1] = (unsigned char)((x >> 8) & 0xff);
msghead.times[0] = (unsigned char)(m->times_read & 0xff);
msghead.times[1] = (unsigned char)((m->times_read >> 8) & 0xff);
msghead.cost[0] = (unsigned char)(m->cost & 0xff);
msghead.cost[1] = (unsigned char)((m->cost >> 8) & 0xff);
msghead.dest_net[0] = (unsigned char)(m->to.net & 0xff);
msghead.dest_net[1] = (unsigned char)((m->to.net >> 8) & 0xff);
msghead.dest[0] = (unsigned char)(m->to.node & 0xff);
msghead.dest[1] = (unsigned char)((m->to.node >> 8) & 0xff);
if (m->isfrom != NULL)
{
size_t len_from;
len_from = strlen(m->isfrom);
memcpy(msghead.from,
m->isfrom,
min(sizeof msghead.from, len_from));
}
else
{
msghead.from[0] = '\0';
}
if (m->isto != NULL)
{
size_t len_to;
le